
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Text;
using System.Threading;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;
using System.Workflow.Activities;

namespace TransTaskWithCompensation
{
    /// <summary>
    /// host
    /// </summary>
    class Program
    {
        private static ManualResetEvent MainControlEvent = new ManualResetEvent(false);

        static void Main(string[] args)
        {
        
            // Configure persistence service
            string connString = ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString;

            //
            using (WorkflowRuntime workflowRuntime = new WorkflowRuntime())
            {
                SqlWorkflowPersistenceService persistence = new SqlWorkflowPersistenceService(
                    connString,
                    true,
                    new TimeSpan(0, 0, 20),
                    new TimeSpan(0, 0, 5)
                    );
                
                workflowRuntime.AddService(persistence);

                //add the external data exchange service to the runtime
                ExternalDataExchangeService exchangeService = new ExternalDataExchangeService();
                workflowRuntime.AddService(exchangeService);

                AutoResetEvent waitHandle = new AutoResetEvent(false);
                workflowRuntime.WorkflowIdled += delegate(object sender, WorkflowEventArgs e)
                {
                    LogHelper.LogMessage("Workflow Idled", ConsoleColor.Blue);
                    waitHandle.Set();
                };

                workflowRuntime.WorkflowLoaded += delegate(object sender, WorkflowEventArgs e)
                {
                    // LogHelper.LogMessage("Workflow Loaded", ConsoleColor.Blue);
                    waitHandle.Set();
                };

                workflowRuntime.WorkflowUnloaded += delegate(object sender, WorkflowEventArgs e)
                {
                    //LogHelper.LogMessage("Workflow Unloaded", ConsoleColor.Blue);
                    waitHandle.Set();
                };

                //workflowRuntime.WorkflowPersisted += delegate(object sender, WorkflowEventArgs e)
                //{
                //    waitHandle.Set();
                //};

                workflowRuntime.WorkflowSuspended += delegate(object sender, WorkflowSuspendedEventArgs e)
                {
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    LogHelper.LogMessage("Workflow Suspended: " + e.WorkflowInstance.InstanceId);
                    Console.ForegroundColor = ConsoleColor.White;
                    waitHandle.Set();
                    MainControlEvent.Set();
                };

                workflowRuntime.WorkflowResumed += delegate(object sender, WorkflowEventArgs e)
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    LogHelper.LogMessage("Workflow Resumed");
                    Console.ForegroundColor = ConsoleColor.White;
                    waitHandle.Set();
                };

                workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e)
                {
                    LogHelper.LogMessage("Workflow Completed:" + e.WorkflowInstance.InstanceId, ConsoleColor.Blue);
                    waitHandle.Set();

                    MainControlEvent.Set();
                };

                workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
                {
                    LogHelper.LogException(e.Exception);

                    LogHelper.LogMessage("Workflow Terminated: " + e.WorkflowInstance.InstanceId, ConsoleColor.Blue);
                    waitHandle.Set();
                    MainControlEvent.Set();
                };

                workflowRuntime.WorkflowAborted += delegate(object sender, WorkflowEventArgs e)
                {
                    LogHelper.LogMessage("Workflow Aborted", ConsoleColor.Blue);
                    waitHandle.Set();
                    MainControlEvent.Set();
                };

                workflowRuntime.ServicesExceptionNotHandled += delegate(object sender, ServicesExceptionNotHandledEventArgs e)
                {
                    LogHelper.LogException(e.Exception);
                    waitHandle.Set();
                };

                workflowRuntime.Stopped += delegate(object sender, WorkflowRuntimeEventArgs e)
                {
                    LogHelper.LogMessage("Workflow Stopped. ", ConsoleColor.Blue);
                    waitHandle.Set();

                    MainControlEvent.Set();
                };


                workflowRuntime.Started += delegate(object sender, WorkflowRuntimeEventArgs e)
                {
                    LogHelper.LogMessage("Services started:\n\r", ConsoleColor.Blue);
                    WorkflowRuntime wfrt = (WorkflowRuntime)sender;
                    ICollection<object> services = wfrt.GetAllServices(typeof(object));
                    foreach (object o in services)
                    {
                        LogHelper.LogMessage(o.ToString());
                    }

                    LogHelper.LogMessage("==============================================\r\n\r\n");

                    IEnumerable<SqlPersistenceWorkflowInstanceDescription> workflows =
                        ((SqlWorkflowPersistenceService)persistence).GetAllWorkflows();

                    int count = 0;
                    foreach (SqlPersistenceWorkflowInstanceDescription workflowDesc in workflows)
                    {
                        LogHelper.LogMessage("Load suspended instance, Id:" + workflowDesc.WorkflowInstanceId.ToString(), ConsoleColor.Blue);
                        try
                        {
                            wfrt.GetWorkflow(workflowDesc.WorkflowInstanceId).Resume();
                            ++count;
                        }
                        catch (Exception ex)
                        {
                            LogHelper.LogException(ex);
                        }
                        
                    }

                    if (count == 0)
                    {
                        WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(WorkflowMain));
                        instance.Start();
                    }
                    else
                    {

                        LogHelper.LogMessage("-----------------------------------------------\r\n\r\n", ConsoleColor.Blue);
                    }
                    LogHelper.LogMessage("Workflow started...\r\n\r\n", ConsoleColor.Blue);

                };

                workflowRuntime.StartRuntime();

                waitHandle.WaitOne();

                MainControlEvent.WaitOne();

                workflowRuntime.StopRuntime();

#if (DEBUG)
                Console.ReadLine();
#endif
            }

        }
    }
}

